home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 4
/
Meeting Pearls Vol. IV (1996)(GTI - Schatztruhe)[!].iso
/
Pearls
/
dev
/
Oberon
/
OberonV4
/
system
/
Kepler9.Mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1995-12-10
|
11KB
|
308 lines
Syntax10.Scn.Fnt
MODULE Kepler9;
(* Semesterarbeit Wintersemester 91/92 von Samuel Urech
Erweiterung des Graphikeditors Kepler um Objektklassen f
r geometrische Zeichnungen.
Programmiersprache: Oberon-2 auf Ceres-1
Autor: Samuel Urech, Tannenrauchstrasse 35/107, 8038 Z
Tel. 01 481 92 92 Stud.Nr. 87-906-434
Datum: 8.1.92 Stand: 15.1.92 *)
IMPORT Math, Files, KeplerFrames, KeplerGraphs;
TYPE
Parallel* = POINTER TO ParallelDesc;
ParallelDesc* = RECORD
( KeplerGraphs.PlanetDesc )
END;
RightAngle* = POINTER TO RightAngleDesc;
RightAngleDesc* = RECORD
( KeplerGraphs.PlanetDesc )
END;
Intersection* = POINTER TO IntersectionDesc;
IntersectionDesc* = RECORD
( KeplerGraphs.PlanetDesc )
END;
Extension* = POINTER TO ExtensionDesc;
ExtensionDesc* = RECORD
( KeplerGraphs.PlanetDesc )
END;
Tangent* = POINTER TO TangentDesc;
TangentDesc* = RECORD
( KeplerGraphs.PlanetDesc )
sign* : SHORTINT; (* -1 oder 1 f
r den einen oder anderen Punkt *)
END;
CircleInter* = POINTER TO CircleIntersection; (* by jt and ww *)
CircleIntersection* = RECORD
(KeplerGraphs.PlanetDesc)
sign*: SHORTINT
END;
CircleLineInter* = POINTER TO CircleLineIntersection; (* by jt and ww *)
CircleLineIntersection* = RECORD
(KeplerGraphs.PlanetDesc)
sign*: SHORTINT
END;
(* --------------------------------------- Parallel ---------------------------------------- *)
PROCEDURE ( self : Parallel ) Calc*;
BEGIN (* Calc *)
self.x := self.c.p[ 2 ].x + self.c.p[ 1 ].x - self.c.p[ 0 ].x;
self.y := self.c.p[ 2 ].y + self.c.p[ 1 ].y - self.c.p[ 0 ].y;
END Calc;
PROCEDURE NewParallel*;
VAR new : Parallel;
BEGIN (* NewParallel *)
IF KeplerFrames.nofpts >= 3 THEN
NEW( new );
NEW( new.c );
new.c.nofpts := 3;
KeplerFrames.ConsumePoint( new.c.p[ 0 ] );
KeplerFrames.ConsumePoint( new.c.p[ 1 ] );
KeplerFrames.ConsumePoint( new.c.p[ 2 ] );
new.Calc;
KeplerFrames.Focus.Append( new );
KeplerFrames.Focus.FlipSelection( new );
END; (* IF *)
END NewParallel;
(* --------------------------------------- Right Angle ---------------------------------------- *)
PROCEDURE ( self : RightAngle ) Calc*;
VAR x0, y0, x1, y1, x2, y2 : LONGINT;
f : REAL;
BEGIN (* Calc *)
x0 := self.c.p[ 0 ].x;
y0 := self.c.p[ 0 ].y;
x1 := self.c.p[ 1 ].x;
y1 := self.c.p[ 1 ].y;
x2 := self.c.p[ 2 ].x;
y2 := self.c.p[ 2 ].y;
f := ( ( x1 - x0 ) * ( x2 - x0 ) + ( y1 - y0 ) * ( y2 - y0 ) ) / ( ( x1 - x0 ) * ( x1 - x0 ) + ( y1 - y0 ) * ( y1 - y0 ) );
self.x := SHORT( ENTIER( x0 + ( x1 - x0 ) * f ) );
self.y := SHORT( ENTIER( y0 + ( y1 - y0 ) * f ) );
END Calc;
PROCEDURE NewRightAngle*;
VAR new : RightAngle;
BEGIN (* NewRightAngle *)
IF KeplerFrames.nofpts >= 3 THEN
NEW( new );
NEW( new.c );
new.c.nofpts := 3;
KeplerFrames.ConsumePoint( new.c.p[ 0 ] );
KeplerFrames.ConsumePoint( new.c.p[ 1 ] );
KeplerFrames.ConsumePoint( new.c.p[ 2 ] );
new.Calc;
KeplerFrames.Focus.Append( new );
KeplerFrames.Focus.FlipSelection( new );
END; (* IF *)
END NewRightAngle;
(* --------------------------------------- Line * Line Intersection ---------------------------------------- *)
PROCEDURE ( self : Intersection ) Calc*;
VAR f, x0, y0, x1, y1, x2, y2, x3, y3 : LONGINT;
BEGIN (* Calc *)
x0 := self.c.p[ 0 ].x;
y0 := self.c.p[ 0 ].y;
x1 := self.c.p[ 1 ].x;
y1 := self.c.p[ 1 ].y;
x2 := self.c.p[ 2 ].x;
y2 := self.c.p[ 2 ].y;
x3 := self.c.p[ 3 ].x;
y3 := self.c.p[ 3 ].y;
f := ( x3 - x2 ) * ( y1 - y0 ) - ( x1 - x0 ) * ( y3 - y2 );
IF f # 0 THEN (* sonst alte Werte beibehalten *)
self.x := SHORT( ( ( x3 - x2 ) * ( x1 - x0 ) * ( y2 - y0 ) + ( x3 - x2 ) * ( y1 - y0 ) * x0 - ( x1 - x0 ) * ( y3 - y2 ) * x2 ) DIV f );
self.y := SHORT( ( ( y3 - y2 ) * ( y1 - y0 ) * ( x2 - x0 ) + ( y3 - y2 ) * ( x1 - x0 ) * y0 - ( y1 - y0 ) * ( x3 - x2 ) * y2 ) DIV ( - f ) );
END; (* IF *)
END Calc;
PROCEDURE NewLineIntersection*;
VAR new : Intersection;
BEGIN (* NewIntersection *)
IF KeplerFrames.nofpts >= 4 THEN
NEW( new );
NEW( new.c );
new.c.nofpts := 4;
KeplerFrames.ConsumePoint( new.c.p[ 0 ] );
KeplerFrames.ConsumePoint( new.c.p[ 1 ] );
KeplerFrames.ConsumePoint( new.c.p[ 2 ] );
KeplerFrames.ConsumePoint( new.c.p[ 3 ] );
new.Calc;
KeplerFrames.Focus.Append( new );
KeplerFrames.Focus.FlipSelection( new );
END; (* IF *)
END NewLineIntersection;
(* --------------------------------------- Circle * Circle Intersection ---------------------------------------- *)
PROCEDURE (self : CircleInter) Calc*;
VAR M1x, M2x, M1y, M2y, R1x, R2x, R1y, R2y,
mx, my, d, c, s, r1, r2, qx, qy, h: REAL;
BEGIN
M1x := self.c.p[0].x; M2x := self.c.p[2].x;
M1y := self.c.p[0].y; M2y := self.c.p[2].y;
R1x := self.c.p[1].x; R2x := self.c.p[3].x;
R1y := self.c.p[1].y; R2y := self.c.p[3].y;
mx := M2x - M1x; my := M2y - M1y; d := Math.sqrt(mx * mx + my * my);
IF d # 0 THEN
c := my / d; s := -mx / d;
r1 := (M1x - R1x) * (M1x - R1x) + (M1y - R1y) * (M1y - R1y);
r2 := (M2x - R2x) * (M2x - R2x) + (M2y - R2y) * (M2y - R2y);
qy := (d + (r1 - r2) / d) / 2;
h := r1 - qy * qy;
IF h >= 0 THEN
qx := self.sign * Math.sqrt(h);
self.x := SHORT(ENTIER(c * qx - s * qy + M1x));
self.y := SHORT(ENTIER(s * qx + c * qy + M1y))
END
END
END Calc;
PROCEDURE (self : CircleInter) Read*(VAR r : Files.Rider);
BEGIN
Files.Read(r, self.sign);
self.Read^(r);
END Read;
PROCEDURE (self : CircleInter) Write*(VAR r : Files.Rider);
BEGIN
Files.Write(r, self.sign);
self.Write^(r);
END Write;
PROCEDURE NewCircleIntersection*;
VAR new1, new2 : CircleInter;
BEGIN
IF KeplerFrames.nofpts >= 4 THEN
NEW(new1); new1.sign := 1; NEW(new1.c ); new1.c.nofpts := 4;
NEW(new2); new2.sign := -1; NEW(new2.c ); new2.c.nofpts := 4;
KeplerFrames.ConsumePoint(new1.c.p[0]); (* middle 1 *)
KeplerFrames.ConsumePoint(new1.c.p[1]); (* periphery 1 *)
KeplerFrames.ConsumePoint(new1.c.p[2]); (* middle 2 *)
KeplerFrames.ConsumePoint(new1.c.p[3]); (* periphery 2 *)
new2.c.p[0] := new1.c.p[0]; INC(new1.c.p[0].refcnt);
new2.c.p[1] := new1.c.p[1]; INC(new1.c.p[1].refcnt);
new2.c.p[2] := new1.c.p[2]; INC(new1.c.p[2].refcnt);
new2.c.p[3] := new1.c.p[3]; INC(new1.c.p[3].refcnt);
new1.Calc; new2.Calc;
KeplerFrames.Focus.Append(new1); KeplerFrames.Focus.Append(new2);
KeplerFrames.Focus.FlipSelection(new1); KeplerFrames.Focus.FlipSelection(new2)
END
END NewCircleIntersection;
(* --------------------------------------- Circle * Line Intersection ---------------------------------------- *)
PROCEDURE (self : CircleLineInter) Calc*;
VAR M1x, L1x, M1y, L1y, R1x, L2x, R1y, L2y, M2x, M2y,
mx, my, d, c, s, r1, qy, h: REAL;
BEGIN
M1x := self.c.p[0].x; L1x := self.c.p[2].x;
M1y := self.c.p[0].y; L1y := self.c.p[2].y;
R1x := self.c.p[1].x; L2x := self.c.p[3].x;
R1y := self.c.p[1].y; L2y := self.c.p[3].y;
mx := L2x - L1x; my := L2y - L1y; d := Math.sqrt(mx * mx + my * my);
IF d # 0 THEN
c := my / d; s := -mx / d;
r1 := (M1x - R1x) * (M1x - R1x) + (M1y - R1y) * (M1y - R1y);
M1x := M1x - L2x; M1y := M1y - L2y;
M2x := c * M1x + s * M1y; M2y := c * M1y - s * M1x;
h := r1 - M2x * M2x;
IF h >= 0 THEN
qy := self.sign * Math.sqrt(h) + M2y;
self.x := SHORT(ENTIER(-s * qy + L2x));
self.y := SHORT(ENTIER(c * qy + L2y))
END
END
END Calc;
PROCEDURE (self : CircleLineInter) Read*(VAR r : Files.Rider);
BEGIN
Files.Read(r, self.sign);
self.Read^(r);
END Read;
PROCEDURE (self : CircleLineInter) Write*(VAR r : Files.Rider);
BEGIN
Files.Write(r, self.sign);
self.Write^(r);
END Write;
PROCEDURE NewCircleLineIntersect*;
VAR new1, new2 : CircleLineInter;
BEGIN
IF KeplerFrames.nofpts >= 4 THEN
NEW(new1); new1.sign := 1; NEW(new1.c ); new1.c.nofpts := 4;
NEW(new2); new2.sign := -1; NEW(new2.c ); new2.c.nofpts := 4;
KeplerFrames.ConsumePoint(new1.c.p[0]); (* middle 1 *)
KeplerFrames.ConsumePoint(new1.c.p[1]); (* periphery 1 *)
KeplerFrames.ConsumePoint(new1.c.p[2]); (* line start *)
KeplerFrames.ConsumePoint(new1.c.p[3]); (* line end *)
new2.c.p[0] := new1.c.p[0]; INC(new1.c.p[0].refcnt);
new2.c.p[1] := new1.c.p[1]; INC(new1.c.p[1].refcnt);
new2.c.p[2] := new1.c.p[2]; INC(new1.c.p[2].refcnt);
new2.c.p[3] := new1.c.p[3]; INC(new1.c.p[3].refcnt);
new1.Calc; new2.Calc;
KeplerFrames.Focus.Append(new1); KeplerFrames.Focus.Append(new2);
KeplerFrames.Focus.FlipSelection(new1); KeplerFrames.Focus.FlipSelection(new2)
END
END NewCircleLineIntersect;
(* --------------------------------------- Extension ---------------------------------------- *)
PROCEDURE ( self : Extension ) Calc*;
BEGIN (* Calc *)
self.x := 2 * self.c.p[ 1 ].x - self.c.p[ 0 ].x;
self.y := 2 * self.c.p[ 1 ].y - self.c.p[ 0 ].y;
END Calc;
PROCEDURE NewExtension*;
VAR new : Extension;
BEGIN (* NewExtension *)
IF KeplerFrames.nofpts >= 2 THEN
NEW( new );
NEW( new.c );
new.c.nofpts := 2;
KeplerFrames.ConsumePoint( new.c.p[ 0 ] );
KeplerFrames.ConsumePoint( new.c.p[ 1 ] );
new.Calc;
KeplerFrames.Focus.Append( new );
KeplerFrames.Focus.FlipSelection( new );
END; (* IF *)
END NewExtension;
(* --------------------------------------- Tangent ---------------------------------------- *)
PROCEDURE ( self : Tangent ) Calc*;
VAR x0, x1, x2, y0, y1, y2 : LONGINT;
r2, d2, x3, y3, faktor : REAL;
BEGIN (* Calc *)
x0 := self.c.p[ 0 ].x;
x1 := self.c.p[ 1 ].x;
x2 := self.c.p[ 2 ].x;
y0 := self.c.p[ 0 ].y;
y1 := self.c.p[ 1 ].y;
y2 := self.c.p[ 2 ].y;
r2 := ( x1 - x0 ) * ( x1 - x0 ) + ( y1 - y0 ) * ( y1 - y0 );
d2 := ( x2 - x0 ) * ( x2 - x0 ) + ( y2 - y0 ) * ( y2 - y0 );
IF r2 < d2 THEN (* Punkt liegt ausserhalb des Kreises *)
x3 := x0 + ( x2 - x0 ) * r2 / d2;
y3 := y0 + ( y2 - y0 ) * r2 / d2;
faktor := Math.sqrt( r2 / d2 - r2 * r2 / d2 / d2 );
self.x := SHORT( ENTIER( x3 + self.sign * faktor * ( y2 - y0 ) ) );
self.y := SHORT( ENTIER( y3 + self.sign * faktor * ( x0 - x2 ) ) );
END; (* IF *)
END Calc;
PROCEDURE ( self : Tangent ) Read*( VAR r : Files.Rider );
BEGIN
Files.Read( r, self.sign );
self.Read^( r );
END Read;
PROCEDURE ( self : Tangent ) Write*( VAR r : Files.Rider );
BEGIN
Files.Write( r, self.sign );
self.Write^( r );
END Write;
PROCEDURE NewTangent*;
VAR new : Tangent;
p0, p1, p2 : KeplerGraphs.Star;
i : SHORTINT;
BEGIN
IF KeplerFrames.nofpts >= 3 THEN
KeplerFrames.ConsumePoint( p0 ); INC( p0.refcnt );
KeplerFrames.ConsumePoint( p1 ); INC( p1.refcnt );
KeplerFrames.ConsumePoint( p2 ); INC( p2.refcnt );
FOR i := 0 TO 1 DO
NEW( new );
new.sign := 2 * i - 1;
NEW( new.c );
new.c.nofpts := 3;
new.c.p[ 0 ] := p0;
new.c.p[ 1 ] := p1;
new.c.p[ 2 ] := p2;
new.Calc;
KeplerFrames.Focus.Append( new );
KeplerFrames.Focus.FlipSelection( new );
END
END
END NewTangent;
END Kepler9.